package com.xue.aspect;

import com.xue.Utils.CurrentHolder;
import com.xue.annotation.LogOperation;
import com.xue.mapper.OperateLogMapper;
import com.xue.pojo.OperateLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Component
@Aspect //当前类为切面类
@Slf4j
@Order(2)  //切面类的执行顺序（前置通知：数字越小先执行; 后置通知：数字越小越后执行）
public class OperationAspect {

    /*execution(访问修饰符?  返回值  包名.类名.?方法名(方法参数) throws 异常?)*/
    @Pointcut("execution(* com.xue.service.impl.DeptServiceImpl.*(..))")//抽取切入点表达式
    private void pt() {
    }

    @Autowired
    private OperateLogMapper operateLogMapper;

    /*@Around("pt()")*/
    @Around("@annotation(log)")//注解@LofOperation被声明到了形参里，所以这里可以获取到注解
    public Object recordTime(ProceedingJoinPoint joinPoint, LogOperation log) throws Throwable {//连接点是可以被aop控制的方法
        // 记录开始时间
        long startTime = System.currentTimeMillis();
        // 执行方法
        Object result = joinPoint.proceed();
        // 当前时间
        long endTime = System.currentTimeMillis();
        // 耗时
        long costTime = endTime - startTime;

        // 构建日志对象
        OperateLog operateLog = new OperateLog();
        operateLog.setOperateEmpId(getCurrentUserId()); // 需要实现 getCurrentUserId 方法
        operateLog.setOperateTime(LocalDateTime.now());
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        operateLog.setMethodName(joinPoint.getSignature().getName());
        operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs()));
        operateLog.setReturnValue(result.toString());
        operateLog.setCostTime(costTime);

        // 插入日志
        operateLogMapper.insert(operateLog);
        return result;
    }

    // 示例方法，获取当前用户ID
    private int getCurrentUserId() {
        return CurrentHolder.getCurrentId();
    }
}